/**
 * @author Chris Ray
 * Created on 5:50:42 AM Oct 30, 2011
 *
 */
package view;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import worldModel.Item;
import worldModel.LargeHeal;
import worldModel.MediumHeal;
import worldModel.Navigator;
import worldModel.SmallHeal;

import battleFieldModel.StopTradeException;
import battleFieldModel.TradeModel;

/**
 * @author Chris Ray Created on 5:50:42 AM Oct 30, 2011
 */
@SuppressWarnings("serial")
public class TradeView extends MasterViewPanel {

	private TradeModel tm;
	private DefaultListModel navListModel;
	private DefaultListModel givingListModel;
	private DefaultListModel receivingListModel;
	private JList LstNavigatorList;
	private JList LstGivingList;
	private JList LstReceivingList;
	private JButton add, rem, conf, btnQuit;

	private boolean seenOffer = false, madeOffer = false, gaveConf = false,
			gotConf = false;

	Navigator currentNav = null;
	private JButton btnHostTrade, btnPartInTrade;

	/**
	 * @param m
	 * @author Chris Ray Created on 5:53:20 AM Oct 30, 2011
	 * 
	 */
	public TradeView(MasterView m) {
		super(m);
		tm = new TradeModel();

		LoadNavigator();
		setUpGui();
		setUpLayout();

	}

	@Override
	public String toString() {
		return "TRADE";
	}

	/**
	 * 
	 * @author Chris Ray Created on 8:09:33 PM Oct 30, 2011
	 * 
	 */
	private void LoadNavigator() {
		try {
			currentNav = Library.loadNavigator();
		}
		// from this point on we either have a null Navigator or a non-null
		// navigator for currentNav
		catch (FileNotFoundException e) {

			currentNav = Library.makeNavigator();
			save();

		} catch (Exception e) {
		}

		// now we have a non null Navigator in currentNav
		// ////////////////////////////////////////////////////////////////////////////////////////////////

		// add navigator's inventory to navigatorList in TM
		tm.getNavigatorList().addAll(currentNav.getInventory());

	}

	/**
	 * 
	 * @author Chris Ray Created on 6:04:37 AM Oct 30, 2011
	 * 
	 */
	private void setUpLayout() {

		this.setLayout(new GridLayout(2, 1));
	}

	/**
	 * After loading/creating the Navigator, bring up a graphical interface with
	 * three JLists (see UML for TradeModel), and four buttons: Quit, Trade,
	 * Host Trade, and Participate in Trade. The three lists are: the
	 * Navigator's inventory, a temporary list for what Items you're giving up,
	 * and a temporary list for what Items you'll be receiving. The layout of
	 * the graphical interface does not matter, as long as the information is
	 * clear.
	 * 
	 * @author Chris Ray Created on 9:32:24 PM Oct 30, 2011
	 * 
	 */
	private void setUpGui() {
		navListModel = new DefaultListModel();
		// iterate through tm.getNavigatorList() adding each item to
		// navListModel
		for (Item i : tm.getNavigatorList())
			navListModel.addElement(i);

		receivingListModel = new DefaultListModel();
		givingListModel = new DefaultListModel();

		LstNavigatorList = new JList(navListModel);
		LstGivingList = new JList(givingListModel);
		LstReceivingList = new JList(receivingListModel);

		JScrollPane navScroll = new JScrollPane(LstNavigatorList);
		JScrollPane givScroll = new JScrollPane(LstGivingList);
		JScrollPane recScroll = new JScrollPane(LstReceivingList);

		btnQuit = new JButton("Quit");
		btnQuit.addActionListener(new QuitListener());
		JButton btnTrade = new JButton("Trade");
		btnTrade.addActionListener(new DebugListener());
		btnTrade.addActionListener(new InitiateTradeListener());
		btnHostTrade = new JButton("Host Trade");
		btnHostTrade.addActionListener(new HostTradeListener());
		btnPartInTrade = new JButton("Participate In Trade");
		btnPartInTrade.addActionListener(new participateInTradeListener());

		// ////////////////////////////////////////////////////////////////////
		// /this will be the implementation of the
		// modified gui that will look nicer:
		// these two panels enable a different layout for the buttons and lists.

		JPanel buttonBody = new JPanel();
		buttonBody.setLayout(new GridLayout(2, 2));

		buttonBody.add(btnQuit);
		buttonBody.add(btnTrade);
		buttonBody.add(btnHostTrade);
		buttonBody.add(btnPartInTrade);

		JPanel listBody = new JPanel();
		listBody.setLayout(new GridLayout(1, 3));

		// going to fix the list issue and all those bugs in a few lines
		JPanel navPan = new JPanel(), givPan = new JPanel(), recPan = new JPanel();

		add = new JButton("Add");
		rem = new JButton("Remove");
		conf = new JButton("Send Offer");

		// place action listeners on buttons
		add.addActionListener(new AddListener());
		rem.addActionListener(new RemListener());
		conf.addActionListener(new ConfListener());

		// making a panel for navigator list stuff
		navPan.setLayout(new BoxLayout(navPan, BoxLayout.PAGE_AXIS));
		navPan.add(new JLabel("Inventory:"));
		// navPan.add(LstNavigatorList);
		navPan.add(navScroll);
		navPan.add(add);

		// making a pane for the giving panel
		givPan.setLayout(new BoxLayout(givPan, BoxLayout.PAGE_AXIS));
		givPan.add(new JLabel("Giving"));
		givPan.add(givScroll);
		givPan.add(rem);

		// making a panel for receiving
		recPan.setLayout(new BoxLayout(recPan, BoxLayout.PAGE_AXIS));
		recPan.add(new JLabel("Receiving"));
		recPan.add(recScroll);
		recPan.add(conf);

		listBody.add(navPan);
		listBody.add(givPan);
		listBody.add(recPan);
		this.add(buttonBody);
		this.add(listBody);

		// make buttons unclickable until connection is established.
		add.setEnabled(false);
		rem.setEnabled(false);
		conf.setEnabled(false);

	}

	// save writes the current navigator to Navigator.dat
	public void save() {
		try {
			Library.saveNavigator(currentNav);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// tells the trade model to send out an offer
	public void giveOffer() {

		tm.sendOffer();
		madeOffer = true;
	}

	// lets retrieves a list of what will be trade
	
	public void receiveOffer() {
		
		try {
			tm.getOffer();
		} catch (StopTradeException e) {
			btnQuit.doClick();
		}
		for (Item i : tm.getReceivingList())
			receivingListModel.addElement(i);
		seenOffer = true;

	}

	// get the confirmation for the trade
	public void getConf(boolean b) {

		if (gotConf && gaveConf)
			resolve(true);
	}

	public void resolve(boolean b) {
		if (b) {
			for (Item i : tm.getGivingList())
				currentNav.getInventory().remove(i);
			for (Item i : tm.getReceivingList())
				currentNav.getInventory().add(i);
			conf.setText("done!");
		} else
			conf.setText("Fail Trade!");

		tm.getGivingList().clear();
		tm.getReceivingList().clear();

		setBtn(false);

		seenOffer = false;
		madeOffer = false;
		gaveConf = false;
		gotConf = false;

		save();

	}

	// //////////////////////////////////////////////////////////////////////////
	// Listeners

	class HostTradeListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {

			// makes the new server socket and asks for a connection
			tm.makeServer();
			// disables the button for trading

			btnHostTrade.setEnabled(false);
			// statement show that we're listening

			if (!tm.getConnected())
				btnHostTrade.setEnabled(true);
			else {
				btnPartInTrade.setEnabled(false);
				setBtn(true);

			}

		}

	}

	class participateInTradeListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO start participating in connection

			String ip = JOptionPane.showInputDialog(
					"Enter the IP you would like to connect to:", null);

			// makes the new client attempt to connect to the ip grabbed
			tm.makeClient(ip);

			btnHostTrade.setEnabled(false);
			btnPartInTrade.setEnabled(false);
			// statement show that we're listening

			if (!tm.getConnected()) {
				btnHostTrade.setEnabled(true);
				btnPartInTrade.setEnabled(true);
			} else {
				System.out.println("Waiting for offer...");
				receiveOffer();
				setBtn(true);

			}

		}

	}

	class InitiateTradeListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {

			for (Item i : tm.getGivingList()) {
				navListModel.removeElement(i);
				tm.getNavigatorList().remove(i);
			}
			for (Item i : tm.getReceivingList())
				System.out.println(i.toString());

		}

	}

	class QuitListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// should exit the trade.
			tm.done();
			m.changeView(Views.TITLE, null);

		}

	}

	public void setBtn(boolean b) {
		if (!madeOffer) {
			add.setEnabled(b);
			rem.setEnabled(b);
		}
		conf.setEnabled(b);

	}

	class AddListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (LstNavigatorList.getSelectedIndex() > -1) {
				tm.getGivingList().add(
						tm.getNavigatorList().get(
								LstNavigatorList.getSelectedIndex()));
				tm.getNavigatorList().remove(
						LstNavigatorList.getSelectedIndex());
				givingListModel.addElement(LstNavigatorList.getSelectedValue());
				navListModel.removeElement(LstNavigatorList.getSelectedValue());
			}
		}

	}

	class RemListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (LstGivingList.getSelectedIndex() > -1) {
				tm.getNavigatorList().add(
						tm.getGivingList()
								.get(LstGivingList.getSelectedIndex()));
				tm.getGivingList().remove(LstGivingList.getSelectedIndex());

				navListModel.addElement(LstGivingList.getSelectedValue());
				givingListModel.removeElement(LstGivingList.getSelectedValue());
			}
		}

	}

	class ConfListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			if (!madeOffer) {
				setBtn(false);
				conf.setText("waiting");
				giveOffer();
				if (!seenOffer) {

					receiveOffer();
					conf.setText("Confirm");
					setBtn(true);
				} else {
					try {
						gotConf = tm.getConf();
					} catch (StopTradeException e) {
						// TODO Auto-generated catch block
						btnQuit.doClick();
						
					}
					setBtn(true);
				}

			} else if (!gotConf) {
				tm.sendConf(true);
				gaveConf = true;
				gotConf = true;
				try {
					resolve(tm.getConf());
				} catch (StopTradeException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					btnQuit.doClick();
				}

			} else {
				tm.sendConf(true);
				gaveConf = true;
				gotConf = true;
				getConf(true);
			}

		}
	}

	class DebugListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// save();
			if (conf.isEnabled())
				conf.doClick();

		}

	}
}
